#!/bin/bash

# SPAM3UK 生产环境部署脚本
# 版本: SPAM3UK-DETAILSREADY-C1
# 目标服务器: 118.145.200.164

set -e  # 遇到错误立即退出

echo "🚀 开始部署 SPAM3UK-DETAILSREADY-C1 到生产环境..."

# 配置变量
DEPLOY_DIR="/data/prod/spam3uk"
BACKUP_DIR="/data/prod/backup"
SERVICE_NAME="spam3uk"
PORT="5700"
DB_NAME="spam3uk_prod"
DB_USER="spam3uk_user"
DB_PASS="Spam3UK_Prod_2025!"
TARGET_TAG="SPAM3UK-DETAILSREADY-C1"
BACKUP_DATE=$(date +"%Y%m%d_%H%M%S")

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为root用户或有sudo权限
check_privileges() {
    if [[ $EUID -eq 0 ]]; then
        SUDO=""
    else
        SUDO="sudo"
        log_info "检测到非root用户，将使用sudo执行管理命令"
    fi
}

# 环境检查
check_environment() {
    log_info "检查系统环境..."
    
    # 检查操作系统
    if ! grep -q "Ubuntu" /etc/os-release; then
        log_warn "当前系统不是Ubuntu，可能需要调整部署命令"
    fi
    
    # 检查Go环境
    if ! command -v go &> /dev/null; then
        log_error "Go环境未安装，请先安装Go 1.19+"
        exit 1
    else
        GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//')
        log_info "检测到Go版本: $GO_VERSION"
    fi
    
    # 检查数据库
    if ! command -v mysql &> /dev/null; then
        log_error "MySQL/MariaDB未安装，请先安装数据库"
        exit 1
    else
        log_info "数据库环境检查通过"
    fi
    
    # 检查Git
    if ! command -v git &> /dev/null; then
        log_error "Git未安装，请先安装Git"
        exit 1
    fi
}

# 创建部署目录
setup_directories() {
    log_info "创建部署目录..."
    $SUDO mkdir -p $DEPLOY_DIR
    $SUDO mkdir -p $BACKUP_DIR
    $SUDO mkdir -p $DEPLOY_DIR/logs
    $SUDO mkdir -p $DEPLOY_DIR/exports
    $SUDO chown -R $(whoami):$(whoami) $DEPLOY_DIR
    $SUDO chown -R $(whoami):$(whoami) $BACKUP_DIR
}

# 备份现有部署
backup_existing_deployment() {
    if [ -d "$DEPLOY_DIR" ] && [ "$(ls -A $DEPLOY_DIR 2>/dev/null)" ]; then
        log_info "检测到现有部署，开始备份..."
        
        # 获取当前版本信息
        CURRENT_VERSION="unknown"
        if [ -f "$DEPLOY_DIR/.git/HEAD" ]; then
            cd $DEPLOY_DIR
            CURRENT_VERSION=$(git describe --tags 2>/dev/null || git rev-parse --short HEAD 2>/dev/null || echo "unknown")
        fi
        
        # 创建备份目录名
        BACKUP_NAME="spam3uk-${CURRENT_VERSION}-${BACKUP_DATE}"
        BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
        
        log_info "备份当前版本 $CURRENT_VERSION 到 $BACKUP_PATH"
        
        # 创建备份
        $SUDO mkdir -p $BACKUP_PATH
        $SUDO cp -r $DEPLOY_DIR/* $BACKUP_PATH/ 2>/dev/null || true
        $SUDO chown -R $(whoami):$(whoami) $BACKUP_PATH
        
        # 记录备份信息
        echo "# SPAM3UK 部署备份信息" > $BACKUP_PATH/backup-info.txt
        echo "备份时间: $(date)" >> $BACKUP_PATH/backup-info.txt
        echo "原版本: $CURRENT_VERSION" >> $BACKUP_PATH/backup-info.txt
        echo "新版本: $TARGET_TAG" >> $BACKUP_PATH/backup-info.txt
        echo "备份路径: $BACKUP_PATH" >> $BACKUP_PATH/backup-info.txt
        
        # 记录最新备份路径（用于回滚脚本）
        echo "$BACKUP_PATH" > $BACKUP_DIR/latest-backup.txt
        
        log_info "✅ 备份完成: $BACKUP_PATH"
        
        # 清理旧的部署目录
        rm -rf $DEPLOY_DIR/*
        rm -rf $DEPLOY_DIR/.*git* 2>/dev/null || true
    else
        log_info "未检测到现有部署，跳过备份步骤"
        echo "" > $BACKUP_DIR/latest-backup.txt
    fi
}

# 停止现有服务
stop_existing_service() {
    log_info "检查并停止现有服务..."
    
    # 停止systemd服务
    if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
        log_warn "检测到现有服务正在运行，正在停止..."
        $SUDO systemctl stop $SERVICE_NAME
        sleep 2
        
        # 确认服务已停止
        if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
            log_error "服务停止失败"
            exit 1
        else
            log_info "✅ 服务已停止"
        fi
    fi
    
    # 检查端口占用
    if netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then
        log_warn "端口 $PORT 仍被占用，尝试释放..."
        
        # 获取占用端口的进程
        PROCESSES=$(netstat -tlnp 2>/dev/null | grep ":$PORT " | awk '{print $7}' | cut -d'/' -f1 | sort -u)
        
        for PROCESS in $PROCESSES; do
            if [ ! -z "$PROCESS" ] && [ "$PROCESS" != "-" ]; then
                log_warn "正在终止进程 $PROCESS"
                $SUDO kill -TERM $PROCESS 2>/dev/null || true
                sleep 2
                
                # 如果进程仍在运行，强制终止
                if kill -0 $PROCESS 2>/dev/null; then
                    log_warn "强制终止进程 $PROCESS"
                    $SUDO kill -KILL $PROCESS 2>/dev/null || true
                fi
            fi
        done
        
        # 再次检查端口
        sleep 1
        if netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then
            log_error "无法释放端口 $PORT，请手动检查"
            netstat -tlnp 2>/dev/null | grep ":$PORT "
            exit 1
        else
            log_info "✅ 端口 $PORT 已释放"
        fi
    fi
    
    # 检查spam3uk相关进程
    SPAM_PROCESSES=$(ps aux | grep -E "[s]pam3uk|[S]PAM3UK" | awk '{print $2}')
    if [ ! -z "$SPAM_PROCESSES" ]; then
        log_warn "发现spam3uk相关进程，正在清理..."
        echo "$SPAM_PROCESSES" | xargs $SUDO kill -TERM 2>/dev/null || true
        sleep 2
        
        # 检查是否还有残留进程
        REMAINING=$(ps aux | grep -E "[s]pam3uk|[S]PAM3UK" | awk '{print $2}')
        if [ ! -z "$REMAINING" ]; then
            echo "$REMAINING" | xargs $SUDO kill -KILL 2>/dev/null || true
        fi
    fi
}

# 下载源码
download_source() {
    log_info "下载源码..."
    cd $DEPLOY_DIR
    
    if [ -d ".git" ]; then
        log_info "检测到现有Git仓库，更新代码..."
        git fetch --tags
        git checkout tags/$TARGET_TAG
    else
        log_info "克隆新仓库..."
        git clone https://gitee.com/andershsueh/spam3uk.git .
        git checkout tags/$TARGET_TAG
    fi
    
    log_info "当前代码版本: $(git describe --tags)"
}

# 安装依赖
install_dependencies() {
    log_info "安装Go依赖..."
    cd $DEPLOY_DIR
    go mod download
    go mod verify
}

# 配置数据库
setup_database() {
    log_info "配置数据库..."
    
    # 检查数据库是否存在
    if mysql -u$DB_USER -p$DB_PASS -e "USE $DB_NAME;" 2>/dev/null; then
        log_info "数据库 $DB_NAME 已存在"
    else
        log_info "创建数据库和用户..."
        mysql -u root -p << EOF
CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';
GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';
FLUSH PRIVILEGES;
EOF
    fi
    
    # 执行数据库脚本
    log_info "初始化数据库表..."
    mysql -u$DB_USER -p$DB_PASS $DB_NAME < db_scripts/create_table.sql || true
    mysql -u$DB_USER -p$DB_PASS $DB_NAME < db_scripts/create_trim_tables.sql || true
    mysql -u$DB_USER -p$DB_PASS $DB_NAME < db_scripts/fix_timestamp_fields.sql || true
    mysql -u$DB_USER -p$DB_PASS $DB_NAME < db_scripts/add_trim_detail_link_field.sql || true
}

# 配置应用
configure_application() {
    log_info "配置应用..."
    cd $DEPLOY_DIR
    
    # 复制生产配置模板
    if [ -f "spam4uk-config.prod.template.json" ]; then
        cp spam4uk-config.prod.template.json spam4uk-config.prod.json
        log_info "已创建生产配置文件"
    else
        log_warn "生产配置模板不存在，使用默认配置"
        cp spam3uk-config.json spam4uk-config.prod.json
        # 修改关键配置
        sed -i 's/"port": 8080/"port": 5700/' spam4uk-config.prod.json
        sed -i 's/"environment": "development"/"environment": "production"/' spam4uk-config.prod.json
    fi
}

# 编译应用
build_application() {
    log_info "编译应用..."
    cd $DEPLOY_DIR
    go build -ldflags="-s -w" -o spam3uk-prod main.go
    chmod +x spam3uk-prod
}

# 创建系统服务
create_system_service() {
    log_info "创建系统服务..."
    
    $SUDO tee /etc/systemd/system/$SERVICE_NAME.service > /dev/null << EOF
[Unit]
Description=SPAM3UK Ford Vehicle Information System
After=network.target mysql.service

[Service]
Type=simple
User=$(whoami)
WorkingDirectory=$DEPLOY_DIR
ExecStart=$DEPLOY_DIR/spam3uk-prod
Restart=always
RestartSec=3
Environment=CONFIG_FILE=spam4uk-config.prod.json

[Install]
WantedBy=multi-user.target
EOF

    $SUDO systemctl daemon-reload
    $SUDO systemctl enable $SERVICE_NAME
}

# 启动服务
start_service() {
    log_info "启动服务..."
    $SUDO systemctl start $SERVICE_NAME
    
    # 等待服务启动
    sleep 3
    
    if systemctl is-active --quiet $SERVICE_NAME; then
        log_info "✅ 服务启动成功"
    else
        log_error "❌ 服务启动失败"
        $SUDO journalctl -u $SERVICE_NAME -n 20
        exit 1
    fi
}

# 验证部署
verify_deployment() {
    log_info "验证部署..."
    
    # 检查端口监听
    if netstat -tlnp | grep -q ":$PORT "; then
        log_info "✅ 端口 $PORT 监听正常"
    else
        log_error "❌ 端口 $PORT 未监听"
        exit 1
    fi
    
    # 健康检查
    sleep 2
    if curl -s -f http://localhost:$PORT/health > /dev/null; then
        log_info "✅ 健康检查通过"
    else
        log_error "❌ 健康检查失败"
        exit 1
    fi
    
    # API测试
    if curl -s http://localhost:$PORT/api/vehicles | jq . > /dev/null 2>&1; then
        log_info "✅ API接口正常"
    else
        log_warn "⚠️  API接口测试异常，请检查数据库连接"
    fi
}

# 配置防火墙
configure_firewall() {
    log_info "配置防火墙..."
    if command -v ufw &> /dev/null; then
        $SUDO ufw allow $PORT/tcp
        log_info "已允许端口 $PORT 通过防火墙"
    else
        log_warn "未检测到ufw防火墙，请手动配置"
    fi
}

# 创建回滚脚本
create_rollback_script() {
    log_info "创建回滚脚本..."
    
    LATEST_BACKUP=$(cat $BACKUP_DIR/latest-backup.txt 2>/dev/null || echo "")
    
    cat > $DEPLOY_DIR/rollback.sh << 'EOF'
#!/bin/bash

# SPAM3UK 回滚脚本
# 此脚本用于回滚到上一个版本

set -e

# 配置变量
DEPLOY_DIR="/data/prod/spam3uk"
BACKUP_DIR="/data/prod/backup"
SERVICE_NAME="spam3uk"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查权限
if [[ $EUID -eq 0 ]]; then
    SUDO=""
else
    SUDO="sudo"
fi

# 读取最新备份路径
LATEST_BACKUP=$(cat $BACKUP_DIR/latest-backup.txt 2>/dev/null || echo "")

if [ -z "$LATEST_BACKUP" ] || [ ! -d "$LATEST_BACKUP" ]; then
    log_error "❌ 未找到有效的备份，无法回滚"
    echo "备份目录: $BACKUP_DIR"
    echo "可用备份:"
    ls -la $BACKUP_DIR/ 2>/dev/null || echo "无备份文件"
    exit 1
fi

echo "🔄 SPAM3UK 系统回滚"
echo "当前部署: $DEPLOY_DIR"
echo "备份路径: $LATEST_BACKUP"

# 读取备份信息
if [ -f "$LATEST_BACKUP/backup-info.txt" ]; then
    echo "📋 备份信息:"
    cat "$LATEST_BACKUP/backup-info.txt"
    echo
fi

# 确认回滚
read -p "确认要回滚到上述版本吗? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    log_info "回滚操作已取消"
    exit 0
fi

log_info "开始回滚操作..."

# 停止当前服务
log_info "停止当前服务..."
if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
    $SUDO systemctl stop $SERVICE_NAME
fi

# 备份当前失败的部署
FAILED_BACKUP="$BACKUP_DIR/failed-$(date +%Y%m%d_%H%M%S)"
log_info "备份当前失败的部署到: $FAILED_BACKUP"
$SUDO mkdir -p $FAILED_BACKUP
$SUDO cp -r $DEPLOY_DIR/* $FAILED_BACKUP/ 2>/dev/null || true

# 清理当前部署
log_info "清理当前部署..."
rm -rf $DEPLOY_DIR/*
rm -rf $DEPLOY_DIR/.*git* 2>/dev/null || true

# 恢复备份
log_info "恢复备份版本..."
cp -r $LATEST_BACKUP/* $DEPLOY_DIR/
chmod +x $DEPLOY_DIR/spam3uk-prod 2>/dev/null || true
chmod +x $DEPLOY_DIR/*.sh 2>/dev/null || true

# 启动服务
log_info "启动回滚后的服务..."
$SUDO systemctl start $SERVICE_NAME
sleep 3

# 验证回滚
if systemctl is-active --quiet $SERVICE_NAME; then
    log_info "✅ 回滚成功！服务已启动"
    
    # 健康检查
    if curl -s -f http://localhost:5700/health > /dev/null; then
        log_info "✅ 健康检查通过"
    else
        log_warn "⚠️  健康检查失败，请检查服务状态"
    fi
    
    echo
    echo "🎉 回滚完成！"
    echo "访问地址: http://118.145.200.164:5700"
    echo "查看状态: sudo systemctl status $SERVICE_NAME"
    echo "查看日志: sudo journalctl -u $SERVICE_NAME -f"
else
    log_error "❌ 回滚失败，服务启动异常"
    $SUDO journalctl -u $SERVICE_NAME -n 20
    exit 1
fi
EOF

    chmod +x $DEPLOY_DIR/rollback.sh
    log_info "✅ 回滚脚本已创建: $DEPLOY_DIR/rollback.sh"
}

# 显示部署信息
show_deployment_info() {
    log_info "🎉 部署完成！"
    echo
    echo "📊 部署信息:"
    echo "  版本: $TARGET_TAG"
    echo "  部署路径: $DEPLOY_DIR"
    echo "  服务端口: $PORT"
    echo "  数据库: $DB_NAME"
    echo
    echo "🔗 访问地址:"
    echo "  Web界面: http://118.145.200.164:$PORT"
    echo "  健康检查: http://118.145.200.164:$PORT/health"
    echo "  API文档: http://118.145.200.164:$PORT/api/vehicles"
    echo
    echo "📋 常用命令:"
    echo "  查看服务状态: sudo systemctl status $SERVICE_NAME"
    echo "  查看日志: sudo journalctl -u $SERVICE_NAME -f"
    echo "  重启服务: sudo systemctl restart $SERVICE_NAME"
    echo "  停止服务: sudo systemctl stop $SERVICE_NAME"
    echo "  🔄 回滚到上个版本: ./rollback.sh"
    echo
    if [ ! -z "$(cat $BACKUP_DIR/latest-backup.txt 2>/dev/null)" ]; then
        echo "📦 备份信息:"
        echo "  最新备份: $(cat $BACKUP_DIR/latest-backup.txt)"
        echo "  回滚命令: cd $DEPLOY_DIR && ./rollback.sh"
    fi
}

# 主函数
main() {
    echo "🚀 SPAM3UK 生产环境部署脚本"
    echo "目标版本: $TARGET_TAG"
    echo "部署时间: $(date)"
    echo "================================"
    
    check_privileges
    check_environment
    setup_directories
    stop_existing_service
    backup_existing_deployment
    download_source
    install_dependencies
    setup_database
    configure_application
    build_application
    create_system_service
    start_service
    verify_deployment
    configure_firewall
    create_rollback_script
    show_deployment_info
    
    echo
    log_info "✅ 所有部署步骤完成！"
}

# 执行主函数
main "$@"
